GremlinでSquidプロキシにネットワーク障害注入してみた
こんにちは。AWS事業本部のKyoです。
プロキシで会社の全拠点のインターネット出口を1つに絞る。ラージエンタープライズによくある構成ではないでしょうか。
目的としては帯域節約やアクセス高速化、セキュリティの確保等かと思います。
今回は単純化したモデルを用いて、この構成にGremlinのネットワーク系の障害注入中(レイテンシ、DNS、ブラックホール)を実施してみました。
構成
EC2二台による構成です。
proxy
, client
ともにAmazon Linux2、t2.micro
を利用しています。
proxy
にはSquidとGremlinをセットアップしています。Squidのコンフィグの変更は行っていません。
SquidとGremlinのセットアップ方法は以下のブログをご参照ください。
※GremlinはSTARTER以上のライセンスが必要となります。 ライセンスについてはこちらをご参照ください。
やってみた
コントロール
コントロールとして、client
から障害注入を行わない状態のproxy
を経由し、本ブログDevIOにアクセスしてみます。
計測はtime
コマンドを利用しました。プログラムの呼び出しから終了までにかかった時間であるreal
に注目します。
time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/ (略) real 0m0.147s user 0m0.010s sys 0m0.005s
レイテンシ
一致するすべての出力ネットワークトラフィックに遅延を挿入します。
proxy
に500ms
のレイテンシを120秒間
注入してみます。
同様にclient
からDevIOにアクセスしてみます。
time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/ (略) real 0m6.084s user 0m0.011s sys 0m0.005s
体感レベルでもハッキリとレイテンシが分かりました。
もう一度実行してみます。
time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/ (略) real 0m7.590s user 0m0.006s sys 0m0.011s
若干ばらつきはありますが、500ms
程度のレイテンシが注入されていることが分かります。
DNS
DNSサーバーへのアクセスをブロックします。
proxy
にDNSサーバへのアクセスのブロックを120秒間
実施してみます。
なお本構成においては、DNSによる名前解決はproxy
が担当します。
time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/ curl: (56) Received HTTP code 503 from proxy after CONNECT real 0m35.014s user 0m0.000s sys 0m0.007s
30秒程度で503
エラーが発生しましました。
また、一度エラーが発生したあと再びアクセスを行うと即座にエラーが返ってくるようになりました。
time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/ curl: (56) Received HTTP code 503 from proxy after CONNECT real 0m0.009s user 0m0.006s sys 0m0.000s
ブラックホール
一致するすべてのネットワークトラフィックをドロップします。
proxy
にブラックホールを180秒間
実施してみます。
time curl -x 10.80.254.241:3128 -L https://dev.classmethod.jp/ curl: (7) Failed to connect to 10.80.254.241 port 3128: Connection timed out real 2m9.609s user 0m0.010s sys 0m0.000s
2分程度でタイムアウトが発生しました。DNSサーバのアクセスブロックとは異なるメッセージが確認できました。
※ 参考として、2分以上のレイテンシ注入でも同様のタイムアウトが確認できました。
所感
今回はプロキシにネットワーク系の障害注入を実施してみました。
多くの場合、プロキシは冗長化されていると思いますが、 上記で注入したようなネットワーク障害が発生した際に自信をもってフェイルオーバーされると言えるでしょうか?
自信をもってイエス!とはなかなか答えづらいかと思います。
とくにレイテンシに関しては、通信が遮断されないケースもあるので、検知することもなかなか難しいのではないかと思います。
これらに対するソリューションとして、AWS Well-Architected フレームワークの一節を引用します。
信頼性、障害の管理、REL 12 どのように信頼性をテストしますか?
カオスエンジニアリングを使⽤して回復⼒をテストする: 本番稼働前および運⽤環境に定期的に障害を挿⼊してテストを実⾏します。ワークロードが障害にどのように反応するかの仮説を⽴て、その仮説をテスト結果と⽐較して、⼀致しない場合はプロセスを繰り返します。本番稼働テストがユーザーに影響を与えないようにします。
これを機にプロキシで出口を1つに絞るメリット、デメリットを見直してみてはいかがでしょうか。
構成そのものを変えることはハードルが高くても、チューニングなど出来ることがあるかもしれません。
以上、何かのお役に立てれば幸いです。